package lpca.utils.MazeGenerator 
{
	import lpca.model.*;
	/**
	 * ...
	 * @author E.Plotnikov
	 * MazeGenerator используется для генерации случайной карты
	 * 
	 * Не используется
	 * 
	 */
	public class MazeGenerator // implements IMazeGenerator 
	{
		public static const DENSITYDX_DEFAULT: Number = 0.0025;
		public static const DENSITY_DEFAULT: Number = 0.05;
		private var density: Number = 0.5; // плотность стен по умолчанию
		private var densityDx: Number = 0.01; // приращение плотности с каждой итерацией
		private var iteration: int = 0;
		private var turnOrder: Array;

		public function MazeGenerator() 
		{
			turnOrder = new Array(
			new Array(KMaze.DIR_UP, KMaze.DIR_RIGHT, KMaze.DIR_DOWN, KMaze.DIR_LEFT), 
			new Array(KMaze.DIR_UP, KMaze.DIR_RIGHT, KMaze.DIR_LEFT, KMaze.DIR_DOWN), 
			new Array(KMaze.DIR_UP, KMaze.DIR_DOWN, KMaze.DIR_RIGHT, KMaze.DIR_LEFT), 
			new Array(KMaze.DIR_UP, KMaze.DIR_DOWN, KMaze.DIR_LEFT, KMaze.DIR_RIGHT), 
			new Array(KMaze.DIR_UP, KMaze.DIR_LEFT, KMaze.DIR_RIGHT, KMaze.DIR_DOWN), 
			new Array(KMaze.DIR_UP, KMaze.DIR_LEFT, KMaze.DIR_DOWN, KMaze.DIR_RIGHT), 
			new Array(KMaze.DIR_RIGHT, KMaze.DIR_UP, KMaze.DIR_DOWN, KMaze.DIR_LEFT), 
			new Array(KMaze.DIR_RIGHT, KMaze.DIR_UP, KMaze.DIR_LEFT, KMaze.DIR_DOWN), 
			new Array(KMaze.DIR_RIGHT, KMaze.DIR_DOWN, KMaze.DIR_UP, KMaze.DIR_LEFT), 
			new Array(KMaze.DIR_RIGHT, KMaze.DIR_DOWN, KMaze.DIR_LEFT, KMaze.DIR_UP), 
			new Array(KMaze.DIR_RIGHT, KMaze.DIR_LEFT, KMaze.DIR_UP, KMaze.DIR_DOWN), 
			new Array(KMaze.DIR_RIGHT, KMaze.DIR_LEFT, KMaze.DIR_DOWN, KMaze.DIR_UP), 
			new Array(KMaze.DIR_DOWN, KMaze.DIR_UP, KMaze.DIR_RIGHT, KMaze.DIR_LEFT), 
			new Array(KMaze.DIR_DOWN, KMaze.DIR_UP, KMaze.DIR_LEFT, KMaze.DIR_RIGHT), 
			new Array(KMaze.DIR_DOWN, KMaze.DIR_LEFT, KMaze.DIR_UP, KMaze.DIR_RIGHT), 
			new Array(KMaze.DIR_DOWN, KMaze.DIR_RIGHT, KMaze.DIR_UP, KMaze.DIR_LEFT), 
			new Array(KMaze.DIR_DOWN, KMaze.DIR_RIGHT, KMaze.DIR_LEFT, KMaze.DIR_UP), 
			new Array(KMaze.DIR_DOWN, KMaze.DIR_LEFT, KMaze.DIR_RIGHT, KMaze.DIR_UP), 
			new Array(KMaze.DIR_LEFT, KMaze.DIR_UP, KMaze.DIR_RIGHT, KMaze.DIR_DOWN), 
			new Array(KMaze.DIR_LEFT, KMaze.DIR_UP, KMaze.DIR_DOWN, KMaze.DIR_RIGHT), 
			new Array(KMaze.DIR_LEFT, KMaze.DIR_RIGHT, KMaze.DIR_UP, KMaze.DIR_DOWN), 
			new Array(KMaze.DIR_LEFT, KMaze.DIR_RIGHT, KMaze.DIR_DOWN, KMaze.DIR_UP), 
			new Array(KMaze.DIR_LEFT, KMaze.DIR_DOWN, KMaze.DIR_UP, KMaze.DIR_RIGHT), 
			new Array(KMaze.DIR_LEFT, KMaze.DIR_DOWN, KMaze.DIR_RIGHT, KMaze.DIR_UP));
		}
		
		private function generateMazeIteration(maze: IKMaze, point: Point): void
		{
			var rnd: Number = 0;
			
			var cell: Cell = maze.getCell(point);

			density = density + densityDx; // увеличиваем плотность с каждым шагом
			// можно расположить в цикле, эффект будет другим
			//density = Math.sin(iteration / 10) / 2; // сюда можно подставить произвольную функцию для расчета плотности
			
			if ((cell != null)&&(cell.value != Cell.CELL_EMPTY))
			{	
				maze.setCell(point, new Cell(Cell.CELL_EMPTY)); // очищаем текущую
					
				iteration++; // инкремент счетчика итераций
				
				rnd = Math.random();
				
				for (var counter:int = 0; counter < maze.getMaxDirection(); counter++)
				{		
					if (rnd > density) // со случайной вероятностью, зависящей от текущей плотности
					{
						generateMazeIteration(maze, point.next(this.turnOrder[Math.floor(rnd * 24)][counter]));
					}
				}
				
				point = null; 
				
				return;
					
			}
		}
		
		public function generateMaze(maze: IKMaze, startPoint: Point = null, startDensity: Number = DENSITY_DEFAULT, startDensityDx: Number = DENSITYDX_DEFAULT): void
		// генерация случайного лабиринта
		{
			iteration = 0; // обнуление счетчика итераций
			
			if (this != null) // если объект не null
			{ 
				if (startPoint == null) // установка значения по умолчанию для точки
				{
					startPoint = new Point(Math.ceil(maze.getSizeX() / 2), Math.ceil(maze.getSizeY() / 2));
				}
				
				this.density = startDensity;
				this.densityDx = startDensityDx;
				
				trace('Генерация лабиринта с начальной точкой (', startPoint.x, ', ', startPoint.y, '), начальной плотностью стен', startDensity, 'и начальным приращением плотности', startDensityDx);
				
				var cell: Cell = new Cell(Cell.CELL_WALL); // создание заполненной ячейки
				
				for (var y:int = 1; y <= maze.getSizeY(); y++)
					for (var x:int = 1; x <= maze.getSizeX(); x++)
					{
						// заполнение пространства полными ячейками
						var point: Point = new Point(x, y); // сопоставление точки по переменным цикла
						maze.setCell(point, cell); 
					}
				generateMazeIteration(maze, startPoint); // вызов рекурсии
				maze.setStartPoint(startPoint);
				trace('Завершено, количество итераций:', iteration)
			}
			else
			{
				trace('Maze is null, can not generate.');
			}
		}
	}

}